﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web.UI.Design;
using System.ComponentModel.Design;
using System.Drawing;

namespace AjaxSnippets.Design
{
    public abstract class WizardForm : Form
    {
        private Button _FinishButton;

        public Button ButtonFinish
        {
            get { return _FinishButton; }
        }
        private Button _CancelButton;

        public Button ButtonCancel
        {
            get { return _CancelButton; }
        }
        private TableLayoutPanel tableLayoutPanel1;
        private Panel panel1;
        private Label _WizardStepLabel;
        private Button _ButtonNext;

        public Button ButtonNext
        {
            get { return _ButtonNext; }
        }
        private Button _ButtonPrev;

        public Button ButtonPrev
        {
            get { return _ButtonPrev; }
        }
        private Panel _WizardStepsPlaceholder;
        private Panel panel2;
        private WizardStep _ActiveWizardStep = null;
        public WizardStep ActiveWizardStep
        {
            get { return _ActiveWizardStep; }
        }
        public int ActiveWizardStepIndex
        {
            get
            {
                int index = 0;
                if (_ActiveWizardStep != null)
                {
                    index = _WizardStepsPlaceholder.Controls.IndexOf(_ActiveWizardStep);
                }

                return index;
            }
        }
        public int NumberOfWizardSteps
        {
            get
            {
                return _WizardStepsPlaceholder.Controls.Count;
            }
        }

        private IServiceProvider _ServiceProvider;
        public IServiceProvider ServiceProvider
        {
            get
            {
                return _ServiceProvider;
            }
            set
            {
                _ServiceProvider = value;
            }
        }

        private IWebFormsBuilderUIService _WebFormsBuilderUIService;
        public IWebFormsBuilderUIService WebFormsBuilderUIService
        {
            get
            {
                return _WebFormsBuilderUIService;
            }
            set
            {
                _WebFormsBuilderUIService = value;
            }
        }

        private IWebApplication _WebApplication;
        public IWebApplication WebApplication
        {
            get
            {
                return _WebApplication;
            }
            set
            {
                _WebApplication = value;
            }
        }

        private IDesignerHost _DesignerHost;

        public IDesignerHost DesignerHost
        {
            get { return _DesignerHost; }
            set { _DesignerHost = value; }
        }
        public WizardForm(IServiceProvider serviceProvider)
        {
            _ServiceProvider = serviceProvider;
            _WebFormsBuilderUIService = (IWebFormsBuilderUIService)_ServiceProvider.GetService(typeof(IWebFormsBuilderUIService));
            _WebApplication = (IWebApplication)_ServiceProvider.GetService(typeof(IWebApplication));
            _DesignerHost = (IDesignerHost)_ServiceProvider.GetService(typeof(IDesignerHost));

            this.AutoScaleBaseSize = new Size(5, 14);
            base.HelpButton = true;
            base.MinimizeBox = false;
            base.MaximizeBox = false;
            base.ShowIcon = false;
            base.ShowInTaskbar = false;
            base.StartPosition = FormStartPosition.CenterParent;

            this.Initialize();

            IEnumerable<WizardStep> steps = GetWizardSteps();

            if (steps != null)
            {
                foreach (WizardStep step in steps)
                {
                    this.AddWizardStep(step);
                }
            }

            UpdateWizardButtonState();

            // Notify the first step if we have one
            if(_ActiveWizardStep != null)_ActiveWizardStep.OnActive();
        }
        protected virtual void Initialize()
        {
            this.InitializeComponent();
        }
        private void InitializeComponent()
        {
            this._FinishButton = new System.Windows.Forms.Button();
            this._CancelButton = new System.Windows.Forms.Button();
            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
            this._ButtonNext = new System.Windows.Forms.Button();
            this._ButtonPrev = new System.Windows.Forms.Button();
            this.panel1 = new System.Windows.Forms.Panel();
            this._WizardStepLabel = new System.Windows.Forms.Label();
            this._WizardStepsPlaceholder = new System.Windows.Forms.Panel();
            this.panel2 = new System.Windows.Forms.Panel();
            this.tableLayoutPanel1.SuspendLayout();
            this.panel1.SuspendLayout();
            this.panel2.SuspendLayout();
            this.SuspendLayout();
            // 
            // _FinishButton
            // 
            this._FinishButton.Dock = System.Windows.Forms.DockStyle.Fill;
            this._FinishButton.Location = new System.Drawing.Point(197, 7);
            this._FinishButton.Name = "_FinishButton";
            this._FinishButton.Size = new System.Drawing.Size(89, 31);
            this._FinishButton.TabIndex = 0;
            this._FinishButton.Text = "Finish";
            this._FinishButton.UseVisualStyleBackColor = true;
            this._FinishButton.Click += new System.EventHandler(this._FinishButton_Click);
            // 
            // _CancelButton
            // 
            this._CancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this._CancelButton.Dock = System.Windows.Forms.DockStyle.Fill;
            this._CancelButton.Location = new System.Drawing.Point(292, 7);
            this._CancelButton.Name = "_CancelButton";
            this._CancelButton.Size = new System.Drawing.Size(91, 31);
            this._CancelButton.TabIndex = 0;
            this._CancelButton.Text = "Cancel";
            this._CancelButton.UseVisualStyleBackColor = true;
            this._CancelButton.Click += new System.EventHandler(this._CancelButton_Click);
            // 
            // tableLayoutPanel1
            // 
            this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.tableLayoutPanel1.ColumnCount = 4;
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
            this.tableLayoutPanel1.Controls.Add(this._CancelButton, 3, 0);
            this.tableLayoutPanel1.Controls.Add(this._FinishButton, 2, 0);
            this.tableLayoutPanel1.Controls.Add(this._ButtonNext, 1, 0);
            this.tableLayoutPanel1.Controls.Add(this._ButtonPrev, 0, 0);
            this.tableLayoutPanel1.Location = new System.Drawing.Point(264, 12);
            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
            this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(4);
            this.tableLayoutPanel1.RowCount = 1;
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
            this.tableLayoutPanel1.Size = new System.Drawing.Size(390, 45);
            this.tableLayoutPanel1.TabIndex = 1;
            // 
            // _ButtonNext
            // 
            this._ButtonNext.Dock = System.Windows.Forms.DockStyle.Fill;
            this._ButtonNext.Location = new System.Drawing.Point(102, 7);
            this._ButtonNext.Name = "_ButtonNext";
            this._ButtonNext.Size = new System.Drawing.Size(89, 31);
            this._ButtonNext.TabIndex = 1;
            this._ButtonNext.Text = "Next >";
            this._ButtonNext.UseVisualStyleBackColor = true;
            this._ButtonNext.Click += new System.EventHandler(this._ButtonNext_Click);
            // 
            // _ButtonPrev
            // 
            this._ButtonPrev.Dock = System.Windows.Forms.DockStyle.Fill;
            this._ButtonPrev.Location = new System.Drawing.Point(7, 7);
            this._ButtonPrev.Name = "_ButtonPrev";
            this._ButtonPrev.Size = new System.Drawing.Size(89, 31);
            this._ButtonPrev.TabIndex = 2;
            this._ButtonPrev.Text = "< Previous";
            this._ButtonPrev.UseVisualStyleBackColor = true;
            this._ButtonPrev.Click += new System.EventHandler(this._ButtonPrev_Click);
            // 
            // panel1
            // 
            this.panel1.BackColor = System.Drawing.Color.White;
            this.panel1.Controls.Add(this._WizardStepLabel);
            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel1.Location = new System.Drawing.Point(0, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(657, 59);
            this.panel1.TabIndex = 7;
            // 
            // _WizardStepLabel
            // 
            this._WizardStepLabel.AutoSize = true;
            this._WizardStepLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this._WizardStepLabel.Location = new System.Drawing.Point(13, 18);
            this._WizardStepLabel.Name = "_WizardStepLabel";
            this._WizardStepLabel.Size = new System.Drawing.Size(103, 25);
            this._WizardStepLabel.TabIndex = 0;
            this._WizardStepLabel.Text = "Step Title";
            // 
            // _WizardStepsPlaceholder
            // 
            this._WizardStepsPlaceholder.Dock = System.Windows.Forms.DockStyle.Fill;
            this._WizardStepsPlaceholder.Location = new System.Drawing.Point(0, 59);
            this._WizardStepsPlaceholder.Name = "_WizardStepsPlaceholder";
            this._WizardStepsPlaceholder.Size = new System.Drawing.Size(657, 311);
            this._WizardStepsPlaceholder.TabIndex = 8;
            // 
            // panel2
            // 
            this.panel2.Controls.Add(this.tableLayoutPanel1);
            this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.panel2.Location = new System.Drawing.Point(0, 310);
            this.panel2.Name = "panel2";
            this.panel2.Size = new System.Drawing.Size(657, 60);
            this.panel2.TabIndex = 9;
            // 
            // WizardForm
            // 
            this.AcceptButton = this._FinishButton;
            this.CancelButton = this._CancelButton;
            this.ClientSize = new System.Drawing.Size(657, 370);
            this.Controls.Add(this.panel2);
            this.Controls.Add(this._WizardStepsPlaceholder);
            this.Controls.Add(this.panel1);
            this.Name = "WizardForm";
            this.tableLayoutPanel1.ResumeLayout(false);
            this.panel1.ResumeLayout(false);
            this.panel1.PerformLayout();
            this.panel2.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        private void AddWizardStep(WizardStep wizardStep)
        {
            this._WizardStepsPlaceholder.Controls.Add(wizardStep);
            wizardStep.Left = 0;
            wizardStep.Top = 0;
            wizardStep.Anchor = AnchorStyles.Top | AnchorStyles.Left;
            wizardStep.Dock = DockStyle.Fill;
            wizardStep.Visible = false;
            if (_ActiveWizardStep == null)
            {
                _ActiveWizardStep = wizardStep;
                _WizardStepLabel.Text = wizardStep.StepTitle;
                wizardStep.Visible = true;
            }
        }

        private void UpdateWizardButtonState()
        {
            if (_ActiveWizardStep != null)
            {
                this._ButtonPrev.Enabled = !(this._WizardStepsPlaceholder.Controls.IndexOf(_ActiveWizardStep) == 0);
                this._FinishButton.Enabled = _ActiveWizardStep.CanFinish;
                this._ButtonNext.Enabled = !(this._WizardStepsPlaceholder.Controls.IndexOf(_ActiveWizardStep) == this._WizardStepsPlaceholder.Controls.Count -1);

            }
        }
        public abstract IEnumerable<WizardStep> GetWizardSteps();

        private void _CancelButton_Click(object sender, EventArgs e)
        {
            base.DialogResult = DialogResult.Cancel;
            base.Close();
        }

        private void _FinishButton_Click(object sender, EventArgs e)
        {
            if (_ActiveWizardStep != null)
            {
                _ActiveWizardStep.OnFinish();
            }
            OnFinish();
            base.DialogResult = DialogResult.OK;
            base.Close();
        }

        private void _ButtonNext_Click(object sender, EventArgs e)
        {
            if (ActiveWizardStepIndex < this.NumberOfWizardSteps - 1) 
            {
                if (_ActiveWizardStep != null)
                {
                    _ActiveWizardStep.OnNext();
                    _ActiveWizardStep.Visible = false;
                    _ActiveWizardStep = (WizardStep)_WizardStepsPlaceholder.Controls[ActiveWizardStepIndex + 1];
                    _ActiveWizardStep.Visible = true;
                    _ActiveWizardStep.OnActive();
                    _WizardStepLabel.Text = _ActiveWizardStep.StepTitle;
                    
                }
            }
            UpdateWizardButtonState();
        }

        private void _ButtonPrev_Click(object sender, EventArgs e)
        {
            if (ActiveWizardStepIndex > 0)
            {
                if (_ActiveWizardStep != null)
                {
                    _ActiveWizardStep.OnPrevious();
                    _ActiveWizardStep.Visible = false;
                    _ActiveWizardStep = (WizardStep)_WizardStepsPlaceholder.Controls[ActiveWizardStepIndex - 1];
                    _ActiveWizardStep.Visible = true;
                    _ActiveWizardStep.OnActive();
                    _WizardStepLabel.Text = _ActiveWizardStep.StepTitle;

                }
            }
            UpdateWizardButtonState();
        }

        protected virtual void OnFinish()
        {

        }
    }
}
